package cn.b.sky.schedule.job;

import cn.b.sky.common.utils.SpringBeanUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.Vector;

/**
 * 
 * <strong>Title : GlobalJobListenerManager.java<br></strong>
 * <strong>Package : cn.b.sky.schedule.job<br></strong>
 * <strong>Description : </strong>全局作业监听器管理<br> 
 * <strong>Create on : 2016年7月29日 下午2:27:18<br></strong>
 * <p>
 * @author JunLin.Yang<br>
 * @version <strong>v1.0.0</strong><br>
 * <br>
 * <strong>修改历史:</strong><br>
 * 修改人|修改日期|修改描述<br>
 * -------------------------------------------<br>
 * <br>
 * <br>
 */
public class GlobalJobListenerManager implements JobListener {

  private Log LOGGER = LogFactory.getLog(GlobalJobListenerManager.class);

  private Vector<SortJobListener> jobListeners;

  public GlobalJobListenerManager() {
    //获取Spring上下文所有的监听器实例
    Map<String, SortJobListener> contextJobListenersMap = SpringBeanUtil.getApplicationContext()
        .getBeansOfType(SortJobListener.class);
    if (null != contextJobListenersMap && 0 != contextJobListenersMap.size()) {
      this.jobListeners = new Vector<>(contextJobListenersMap.size());
      this.jobListeners.addAll(contextJobListenersMap.values());

      //按照Order排序
      Collections.sort(this.jobListeners, new Comparator<SortJobListener>() {

        @Override
        public int compare(SortJobListener o1, SortJobListener o2) {
          return o1.getOrder() - o2.getOrder();
        }

      });
    }

  }

  @Override
  public String getName() {
    return "全局监听管理器";
  }

  @Override
  public void jobToBeExecuted(JobExecutionContext context) {
    if (!CollectionUtils.isEmpty(this.jobListeners)) {
      JobListener jobListener;
      for (int i = 0; i < this.jobListeners.size(); i++) {
        jobListener = this.jobListeners.get(i);
        try {
          jobListener.jobToBeExecuted(context);
        } catch (Exception e) {
          LOGGER.error(String.format("调用监听[%s]出错：", jobListener.getName()), e);
        }
      }
    }
  }

  @Override
  public void jobExecutionVetoed(JobExecutionContext context) {
    if (!CollectionUtils.isEmpty(this.jobListeners)) {
      JobListener jobListener;
      //按倒序调用监听器，保证优先级最小的先执行，最高的后执行
      for (int i = this.jobListeners.size() - 1; i >= 0; i--) {
        jobListener = this.jobListeners.get(i);
        try {
          jobListener.jobExecutionVetoed(context);
        } catch (Exception e) {
          LOGGER.error(String.format("调用监听[%s]出错：", jobListener.getName()), e);
        }
      }
    }
  }

  @Override
  public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
    if (!CollectionUtils.isEmpty(this.jobListeners)) {
      JobListener jobListener;
      //按倒序调用监听器，保证优先级最小的先执行，最高的后执行
      for (int i = this.jobListeners.size() - 1; i >= 0; i--) {
        jobListener = this.jobListeners.get(i);
        try {
          jobListener.jobWasExecuted(context, jobException);
        } catch (Exception e) {
          LOGGER.error(String.format("调用监听[%s]出错：", jobListener.getName()), e);
        }
      }
    }
  }

}
